﻿
// DuGuYinView.cpp: CDuGuYinView 类的实现
//

#include "pch.h"
#include "framework.h"
#include "resource.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "DuGuYin.h"
#endif

#include "DuGuYinDoc.h"
#include "DuGuYinView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDuGuYinView

IMPLEMENT_DYNCREATE(CDuGuYinView, CView)

BEGIN_MESSAGE_MAP(CDuGuYinView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CDuGuYinView::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_KEYDOWN()
	ON_COMMAND(ID_32776, &CDuGuYinView::OnOrthogonalProjection)
	ON_COMMAND(ID_32777, &CDuGuYinView::OnObliqueProjection)
	ON_COMMAND(ID_32778, &CDuGuYinView::OnPerspectiveProjection)
	ON_COMMAND(ID_32779, &CDuGuYinView::OnPitchAdjust)
	ON_COMMAND(ID_32780, &CDuGuYinView::OnChangeDirect)
END_MESSAGE_MAP()

// CDuGuYinView 构造/析构

CDuGuYinView::CDuGuYinView() noexcept
{
	isTexture = FALSE;//添加纹理
	// TODO: 在此处添加构造代码
	InitializeLightingScene();
	InitializeTexture();
	if (isTexture) {
		seal.SetScene(pLight, pMaterial, pTexture);
	}
	else {
		seal.SetScene(pLight, pMaterial);
	}
	R = 1200, d = 800;
	Phi = 45.0, Psi = 45.0;
	Alpha = 0.0, Beta = 0.0;
	bPlay = FALSE;
	m_ProjectionType = ProjectionType::PerspectiveProjection;
	/*cube.projection.SetEye(Phi, Psi, R, d);
	cube.ReadPoint();
	cube.ReadFacet();
	transform.SetMatrix(cube.GetVertexArrayName(), 8);*/
	seal.projection.SetEye(Phi, Psi, R, d);
	seal.ReadPoint();
	seal.ReadFacet();
	seal.ReadTexture(pTexture);
	transform.SetMatrix(seal.GetVertexArrayName(), 24);//顶点数组初始化
	double nEdge = 100;
	transform.Scale(nEdge, nEdge, nEdge);
	transform.Translate(-nEdge / 2, -nEdge / 2, -nEdge / 2);
}

void CDuGuYinView::DrawObject(CDC* pDC)
{
	if (m_ProjectionType == ProjectionType::OrthogonalProjection) {
		//cube.Draw(pDC);
		seal.SetX(2);
		plane.Draw(pDC);
		seal.DrawShadow(pDC);
		seal.Draw3(pDC);
	}
	else if (m_ProjectionType == ProjectionType::ObliqueProjection) {
		//cube.Draw2(pDC);
		seal.SetX(1);
		plane.Draw(pDC);
		seal.DrawShadow(pDC);
		seal.Draw3(pDC);
	}
	else if (m_ProjectionType == ProjectionType::PerspectiveProjection)
	{
		seal.SetX(3);
		plane.Draw(pDC);
		seal.DrawShadow(pDC);
		seal.Draw3(pDC);
		//cube.Draw3(pDC);
	}
	else {
		seal.SetX(4);
		plane.Draw(pDC);
		seal.DrawShadow(pDC);
		seal.Draw3(pDC);
	}
}

void CDuGuYinView::DoubleBuffer(CDC* pDC)
{
	CRect rect;//定义客户区矩形
	GetClientRect(&rect);//获得客户区大小
	pDC->SetMapMode(MM_ANISOTROPIC);//pDC自定义坐标系
	pDC->SetWindowExt(rect.Width(), rect.Height()); // 设置窗口范围
	pDC->SetViewportExt(rect.Width(), -rect.Height());//设置视区范围,x轴水平向右，y轴垂直向上
	pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);//客户区中心为原点
	CDC memDC;//内存DC
	memDC.CreateCompatibleDC(pDC);//创建一个与显示pDC兼容的内存memDC
	CBitmap NewBitmap, * pOldBitmap;//内存中承载的临时位图 
	NewBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());//创建兼容位图 
	pOldBitmap = memDC.SelectObject(&NewBitmap);//将兼容位图选入memDC 
	memDC.FillSolidRect(rect, pDC->GetBkColor());//按原来背景填充客户区，否则是黑色
	rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);
	memDC.SetMapMode(MM_ANISOTROPIC);//memDC自定义坐标系
	memDC.SetWindowExt(rect.Width(), rect.Height());
	memDC.SetViewportExt(rect.Width(), -rect.Height());
	memDC.SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
	DrawObject(&memDC);//memDC自定义坐标系
	pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, -rect.Width() / 2, -rect.Height() / 2, SRCCOPY);//将内存memDC中的位图拷贝到显示pDC中
	memDC.SelectObject(pOldBitmap); // 恢复位图
	NewBitmap.DeleteObject();//删除位图
	memDC.DeleteDC();//删除memDC

}

void CDuGuYinView::InitializeLightingScene(void)
{
	nLightNumber = 1;
	pLight = new CLighting(nLightNumber);
	pLight->LightSource[0].SetPosition(800,800, 1000);
	for (int i = 0; i < nLightNumber; i++) {
		pLight->LightSource[i].L_Diffuse = CRGB(0.3, 0.3, 0.3);//漫反射色
		pLight->LightSource[i].L_Specular = CRGB(1.0, 1.0, 1,0);//镜面高光颜色
		pLight->LightSource[i].L_C0 = 1.0;//常数衰减系数
		pLight->LightSource[i].L_C1 = 0.0000001;//线性衰减系数
		pLight->LightSource[i].L_C2 = 0.00000001;//二次衰减系数
		pLight->LightSource[i].L_OnOff = TRUE;//开启光源
	}
	pMaterial = new CMaterial();
	pMaterial->SetAmbient(CRGB(0.1, 0.1, 0.1));//环境反射率
	pMaterial->SetDiffuse(CRGB(0.3, 0.3, 0.3));//漫反射率
	pMaterial->SetSpecular(CRGB(0.5, 0.5, 0.5));//镜面反射率
	pMaterial->SetEmission(CRGB(0, 0, 0));//自发光
	pMaterial->SetExponent(100);//高光指数
	//设置纹理属性
	/*if (isTexture) {
		pTexture = new CTexture();
		pTexture->GetImage(IDB_BITMAP2);
	}*/
}
 
void CDuGuYinView::InitializeTexture(void)
{
	Texture[0].GetImage(IDB_BITMAP1);//北京
	Texture[1].GetImage(IDB_BITMAP2);//上海
	Texture[2].GetImage(IDB_BITMAP3);//广东
	Texture[3].GetImage(IDB_BITMAP17);
	Texture[4].GetImage(IDB_BITMAP4);//浙江
	Texture[5].GetImage(IDB_BITMAP18);
	Texture[6].GetImage(IDB_BITMAP5);//山东
	Texture[7].GetImage(IDB_BITMAP6);//江苏
	Texture[8].GetImage(IDB_BITMAP7);//河南
	Texture[9].GetImage(IDB_BITMAP8);//河北
	Texture[10].GetImage(IDB_BITMAP3);
	Texture[11].GetImage(IDB_BITMAP9);//四川
	Texture[12].GetImage(IDB_BITMAP19);
	Texture[13].GetImage(IDB_BITMAP10);//福建
	Texture[14].GetImage(IDB_BITMAP1);
	Texture[15].GetImage(IDB_BITMAP11);//湖南
	Texture[16].GetImage(IDB_BITMAP13);
	Texture[17].GetImage(IDB_BITMAP12);//贵州
	Texture[18].GetImage(IDB_BITMAP2);
	Texture[19].GetImage(IDB_BITMAP3);
	Texture[20].GetImage(IDB_BITMAP13);//安徽
	Texture[21].GetImage(IDB_BITMAP4);
	Texture[22].GetImage(IDB_BITMAP5);
	Texture[23].GetImage(IDB_BITMAP6);
	Texture[24].GetImage(IDB_BITMAP14);//江西
	Texture[25].GetImage(IDB_BITMAP7);
	pTexture = Texture;
}



CDuGuYinView::~CDuGuYinView()
{
	if (pLight != NULL) {
		delete pLight; 
		pLight = NULL;
	}
}

BOOL CDuGuYinView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CDuGuYinView 绘图

void CDuGuYinView::OnDraw(CDC* pDC)
{
	CDuGuYinDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	
	// TODO: 在此处为本机数据添加绘制代码
	DoubleBuffer(pDC);
}


// CDuGuYinView 打印


void CDuGuYinView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL CDuGuYinView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CDuGuYinView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CDuGuYinView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}

void CDuGuYinView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CDuGuYinView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CDuGuYinView 诊断

#ifdef _DEBUG
void CDuGuYinView::AssertValid() const
{
	CView::AssertValid();
}

void CDuGuYinView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CDuGuYinDoc* CDuGuYinView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDuGuYinDoc)));
	return (CDuGuYinDoc*)m_pDocument;
}
#endif //_DEBUG


// CDuGuYinView 消息处理程序


void CDuGuYinView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (!bPlay)
	{
		if (m_ProjectionType == ProjectionType::ViewTransform1)
		{
			switch (nChar)
			{
			case VK_UP: {
				R += 50;
				seal.projection.SetEye(Phi, Psi, R, d);
				break;
			}
			case VK_DOWN: {
				R -= 50;
				seal.projection.SetEye(Phi, Psi, R, d);
				break;
			}
			default: {
				break; }
			}
			Invalidate(FALSE);
		}
		else if (m_ProjectionType == ProjectionType::ViewTransform2)
		{
			switch (nChar)
			{
			case VK_UP: {
				Phi += 5;
				seal.projection.SetEye(Phi, Psi);
				seal.projection.InitialParameter();
				break;
			}
			case VK_DOWN: {
				Phi -= 5;
				seal.projection.SetEye(Phi, Psi);
				seal.projection.InitialParameter();
				break;
			}
			case VK_LEFT: {
				Psi += 5;
				seal.projection.SetEye(Phi, Psi);
				seal.projection.InitialParameter();
				break;
			}
			case VK_RIGHT: {
				Psi -= 5;
				seal.projection.SetEye(Phi, Psi);
				seal.projection.InitialParameter();
				break;
			}
			default: {
				break; }
			}
			Invalidate(FALSE);
		}
		else
		{
			switch (nChar)
			{
			case VK_UP: {
				Alpha = -5;
				transform.RotateX(Alpha);
				break;
			}
			case VK_DOWN: {
				Alpha = +5;
				transform.RotateX(Alpha);
				break;
			}
			case VK_LEFT: {
				Beta = -5;
				transform.RotateY(Beta);
				break;
			}
			case VK_RIGHT: {
				Beta = +5;
				transform.RotateY(Beta);
				break;
			}
			default: {
				break; }
			}
			Invalidate(FALSE);
		}
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}





void CDuGuYinView::OnOrthogonalProjection()
{
	// TODO: 在此添加命令处理程序代码
	m_ProjectionType = ProjectionType::OrthogonalProjection;
	printf("这是OrthogonalProjection");
	Invalidate();
}


void CDuGuYinView::OnObliqueProjection()
{
	// TODO: 在此添加命令处理程序代码
	m_ProjectionType = ProjectionType::ObliqueProjection;
	printf("这是ObliqueProjection");
	Invalidate();
}


void CDuGuYinView::OnPerspectiveProjection()
{
	// TODO: 在此添加命令处理程序代码
	m_ProjectionType = ProjectionType::PerspectiveProjection;
	printf("这是PerspectiveProjection");
	Invalidate();
}


void CDuGuYinView::OnPitchAdjust()
{
	// TODO: 在此添加命令处理程序代码
	m_ProjectionType = ProjectionType::ViewTransform1;

	Invalidate();
}


void CDuGuYinView::OnChangeDirect()
{
	// TODO: 在此添加命令处理程序代码
	m_ProjectionType = ProjectionType::ViewTransform2;

	Invalidate();
}
